package cn.edu.xmu.tangzk.scala.byexs

import scala.annotation.tailrec

object Ex04_6_1 {

    val EmptyProduct = 1

    def inefficientFactorial(n: Int): Int = {
        assert(n >= 0)

        if (n == 0) EmptyProduct
        else { n * inefficientFactorial(n - 1) }
    }

    def factorial(n: Int): Int = {
        assert(n >= 0)

        @tailrec def factorial(n: Int, result: Int): Int = {
            if (n == 0) result
            else { factorial(n - 1, result * n) }
        }

        factorial(n, EmptyProduct)
    }

    def main(args: Array[String]) {
        var startTime: Long = System.nanoTime()
        val result0 = factorial(5)
        var endTime: Long = System.nanoTime()
        printf("factorial(5) = %d, time elapsed: %d ms\n", result0, (endTime - startTime) / 1000)
        startTime = System.nanoTime()
        val result1 = inefficientFactorial(5)
        endTime = System.nanoTime()
        printf("ineff...factorial(5) = %d, time elapsed: %d ms\n", result1, (endTime - startTime) / 1000)
        assert(result0 == result1)
    }

}